#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5 + 10;

struct node
{
    int d , v , a;
};


int T;
int n , m , L , V;
node car[MAXN];
int p[MAXN];
bool flaga = 1, flagb = 1, flagc = 1;
set<int> S[MAXN];
int ans = 0x3f3f3f3f, cnt;

void dfs(int p , int tot , set<int> now)
{
    if(p == m + 1)
    {
        if(now.size() == cnt)
        {
            ans = min(ans , tot);
        }
        return ;
    }
    dfs(p + 1 , tot , now);
    for(auto i : S[p])
        now.insert(i);
    dfs(p + 1 , tot + 1 , now);
}

bool b_in_a(set<int> a , set<int> b)
{
    if(a.size() < b.size())
        return false;
    for(auto i : b)
        if(a.find(i) == a.end())
            return false;
    return true;
}

bool special_judge()
{
    int cnt = 0;
    if(flaga)
    {
        for(int i = 1 ; i <= n ; i ++)
            if(car[i].v > V && car[i].d <= p[m])
                cnt ++;
        printf("%d " , cnt);
        if(cnt)
            printf("%d\n" , m - 1);
        else
            printf("%d\n" , m);
        return true;
    }
    if(flagb)
    {
        for(int i = 1 ; i <= n ; i ++)
        {
            int d_x = p[m]- car[i].d;
            int now_v_2 = 2 * car[i].a * d_x + car[i].v * car[i].v;
            if(now_v_2 > V * V && car[i].d <= p[m])
                cnt ++;
        }
        printf("%d " , cnt);
        if(cnt)
            printf("%d\n" , m - 1);
        else
            printf("%d\n" , m);
        return true;
    }
    return 0;
}

void search_p(double str , double ed , int id)
{
    int ansl , ansr;
    int l = 1 , r = m;
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if(p[mid] > str)
            r = mid - 1;
        else
            l = mid + 1;
    }
    ansl = r + 1;
    l = ansl , r = m;
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if(p[mid] < ed)
            l = mid + 1;
        else
            r = mid - 1;
    }
    ansr = l - 1;
    for(int i = ansl ; i <= ansr ; i ++)
        S[i].insert(id);
    return ;
}

int main()
{
    freopen("detect.in" , "r" , stdin);
    freopen("detect.out" , "w" , stdout);

    scanf("%d" , &T);
    while (T --)
    {
        cnt = 0 , ans = 0x3f3f3f3f;
        for(int i = 1 ; i <= m ; i ++)
            S[i].clear();
        scanf("%d%d%d%d" , &n , &m , &L , &V);
        for(int i = 1 ; i <= n ; i ++)
        {
            scanf("%d%d%d" , &car[i].d , &car[i].v , &car[i].a);
            if(car[i].a != 0)
                flaga = false;
            if(car[i].a <= 0)
                flagb = false;
            if(car[i].a >= 0)
                flagc = false;
        }
        for(int i = 1 ; i <= m ; i ++)
            scanf("%d" , p + i);
        sort(p + 1 , p + m + 1);
        if(special_judge())
            continue;
        //t1
        cnt = 0;
        for(int i = 1 ; i <= n ; i ++)
        {
            if(car[i].a >= 0)
            {
                int d_x = p[m]- car[i].d;
                int now_v_2 = 2 * car[i].a * d_x + car[i].v * car[i].v;
                if(d_x < 0 || now_v_2 <= 0)
                    continue;
                if(now_v_2  > V * V)
                    cnt ++;
            }
            else
            {
                int l = 1 , r = m;
                while (l <= r)
                {
                    int mid = (l + r) >> 1;
                    if(p[mid] >= car[i].d)
                        r = mid - 1;
                    else
                        l = mid + 1;
                }
                int test_p = r + 1;
                int d_x = p[test_p]- car[i].d;
                int now_v_2 = 2 * car[i].a * d_x + car[i].v * car[i].v;
                if(d_x < 0 || now_v_2 <= 0)
                    continue;
                if(now_v_2  > V * V)
                    cnt ++;
            }
            if(car[i].a == 0)
            {
                if(car[i].v > V)
                    search_p((double)car[i].d - 0.1, p[m] + 0.1 , i);
            }
            else if(car[i].a > 0)
            {
                if(car[i].v > V)
                    search_p((double)car[i].d - 0.1, p[m] + 0.1 , i);
                else
                {
                    double d_x = (double)(V * V - car[i].v * car[i].v) / (double)(2 * car[i].a);
                    if(car[i].d + d_x > p[m])
                        continue;
                    search_p(car[i].d + d_x - 0.1 , p[m] + 0.1 , i);
                }
            }
            else
            {
                if(car[i].v > V)
                {
                    double d_x = (double)(V * V - car[i].v * car[i].v) / (double)(2 * car[i].a);
                    search_p(car[i].d - 0.1, car[i].d + d_x + 0.1 , i);
                }
            }
        }
        printf("%d " , cnt);
        // cout << "kkk" << endl;
        set<int> now;
        dfs(1 , 0 , now);
        printf("%d\n" , m - ans);
        //t2
    }
    
    return 0;
}